package com.kongjs.application.service;

import com.github.dockerjava.api.DockerClient;
import com.github.dockerjava.api.command.LogContainerCmd;
import com.github.dockerjava.api.command.RestartContainerCmd;
import com.github.dockerjava.core.DefaultDockerClientConfig;
import com.github.dockerjava.core.DockerClientImpl;
import com.github.dockerjava.core.InvocationBuilder;
import com.github.dockerjava.httpclient5.ApacheDockerHttpClient;
import com.kongjs.application.properties.DockerProperties;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

@Service
public class DockerOperationService {
    private final DockerProperties dockerProperties;
    private final DockerClient dockerClient;

    public DockerOperationService(DockerProperties dockerProperties) {
        this.dockerProperties = dockerProperties;
        this.dockerClient = initializeDockerClient();
    }
    /*
       DOCKER_HOST Docker 主机 URL，例如 或tcp://localhost:2376 unix:///var/run/docker.sock
       DOCKER_TLS_VERIFY 启用/禁用 TLS 验证（在 和 协议之间切换）http https
       DOCKER_CERT_PATH TLS 验证所需证书的路径
       DOCKER_CONFIG 其他 docker 配置文件的路径（如.dockercfg)
       api.versionAPI 版本，例如 .1.23
       registry.url 您的注册表地址。
       registry.username 您的注册表用户名（推送容器时需要）。
       registry.password 您的注册表密码。
       registry.email 您的注册表电子邮件。
       */
    private DockerClient initializeDockerClient() {
        DefaultDockerClientConfig.Builder dockerClientConfigBuilder = DefaultDockerClientConfig
                .createDefaultConfigBuilder();
        if (StringUtils.hasText(dockerProperties.getDockerHost())) {
            dockerClientConfigBuilder.withDockerHost(dockerProperties.getDockerHost());
        }
        if (!ObjectUtils.isEmpty(dockerProperties.getDockerTlsVerify())) {
            dockerClientConfigBuilder.withDockerTlsVerify(dockerProperties.getDockerTlsVerify());
        }
        if (StringUtils.hasText(dockerProperties.getDockerConfig())) {
            dockerClientConfigBuilder.withDockerConfig(dockerProperties.getDockerConfig());
        }
        if (StringUtils.hasText(dockerProperties.getDockerCertPath())) {
            dockerClientConfigBuilder.withDockerCertPath(dockerProperties.getDockerCertPath());
        }
        if (StringUtils.hasText(dockerProperties.getApiVersion())) {
            dockerClientConfigBuilder.withApiVersion(dockerProperties.getApiVersion());
        }
        if (StringUtils.hasText(dockerProperties.getRegistryUsername())) {
            dockerClientConfigBuilder.withRegistryUsername(dockerProperties.getRegistryUsername());
        }
        if (StringUtils.hasText(dockerProperties.getRegistryPassword())) {
            dockerClientConfigBuilder.withRegistryPassword(dockerProperties.getRegistryPassword());
        }
        if (StringUtils.hasText(dockerProperties.getRegistryEmail())) {
            dockerClientConfigBuilder.withRegistryEmail(dockerProperties.getRegistryEmail());
        }
        if (StringUtils.hasText(dockerProperties.getRegistryUrl())) {
            dockerClientConfigBuilder.withRegistryUrl(dockerProperties.getRegistryUrl());
        }
        DefaultDockerClientConfig dockerClientConfig = dockerClientConfigBuilder.build();
        ApacheDockerHttpClient.Builder httpBuilder = new ApacheDockerHttpClient.Builder();
        ApacheDockerHttpClient dockerHttpClient = httpBuilder
                .dockerHost(dockerClientConfig.getDockerHost())
                .sslConfig(dockerClientConfig.getSSLConfig())
                .maxConnections(dockerProperties.getMaxConnections())
                .connectionTimeout(dockerProperties.getConnectionTimeout())
                .responseTimeout(dockerProperties.getResponseTimeout())
                .build();
        return DockerClientImpl.getInstance(dockerClientConfig, dockerHttpClient);
    }

    public void restartContainer(String containerId) {
        RestartContainerCmd restartContainerCmd = dockerClient.restartContainerCmd(containerId);
        restartContainerCmd.exec();
        LogContainerCmd logContainerCmd = dockerClient.logContainerCmd(containerId);
        logContainerCmd.exec(new InvocationBuilder.AsyncResultCallback<>());
    }
}
